#include "AppSettings.h"

AppSettings::AppSettings(void)
{

}

//-------------------------------------------------------------------------------------------------------------------

AppSettings::~AppSettings(void)
{
}

//------------------------------------------------------------------------------------------------------------------

bool AppSettings::loadSettings(void)
{
	return loadSettings("AppSettings.xml");
}

//-------------------------------------------------------------------------------------------------------------------

bool AppSettings::loadSettings(Ogre::String fileName)
{
	waterSettings.resetToDefault();
	applicationSettings.resetToDefault();
	bool loadOkay = settingsFile.LoadFile(fileName.data());
	if (loadOkay)
	{
		root = settingsFile.FirstChildElement();
		if(root != 0)
		{
			TiXmlElement *waterSettings = root->FirstChildElement("WaterSettings");

			if(waterSettings != 0)
			{
				TiXmlElement *currentParam;
				Ogre::String paramId;
				Ogre::String paramValue;

				currentParam = waterSettings->FirstChildElement();
				while(currentParam != 0)
				{

					paramId = currentParam->Value();

					if(paramId == "MaxParticles")
					{
						paramValue = currentParam->GetText();

						int value = Ogre::StringConverter::parseInt(paramValue);
						this->waterSettings.mMaxParticles = value;
					}
					else if(paramId == "KernelRadiusMultiplier")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mKernelRadiusMultiplier = value;
					}
					else if(paramId == "RestParticlesPerMetre")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mRestParticlesPerMetre = value;
					}
					else if(paramId == "MotionLimitMultiplier")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mMotionLimitMultiplier = value;
					}
					else if(paramId == "PacketSizeMultiplier")
					{
						paramValue = currentParam->GetText();

						int value = Ogre::StringConverter::parseInt(paramValue);
						this->waterSettings.mPacketSizeMultiplier = value;
					}
					else if(paramId == "CollisionDistanceMultiplier")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mCollisionDistanceMultiplier = value;
					}
					else if(paramId == "Stiffness")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mStiffness = value;
					}
					else if(paramId == "Viscosity")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mViscosity = value;
					}
					else if(paramId == "RestDensity")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mRestDensity = value;
					}
					else if(paramId == "StartHeight")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mStartHeight = value;
					}
					else if(paramId == "ParticleLifetime")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mParticleLifetime = value;
					}
					else if(paramId == "Rate")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mRate = value;
					}
					else if(paramId == "FluidSpeed")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mFluidSpeed = value;
					}
					else if(paramId == "ReplusionCoefficient")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mReplusionCoefficient = value;
					}
					else if(paramId == "DimensionX")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mDimensionX = value;
					}
					else if(paramId == "DimensionY")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mDimensionY = value;
					}
					else if(paramId == "ParticleSize")
					{
					
						paramValue = currentParam->GetText();

						Ogre::Real value = Ogre::StringConverter::parseReal(paramValue);
						this->waterSettings.mParticleSize = value;
					}

					currentParam = currentParam->NextSiblingElement();
				}
			}

			//--------------------------

			TiXmlElement *applicationSettings = root->FirstChildElement("ApplicationSettings");

			if(applicationSettings != 0)
			{
				TiXmlElement *currentParam;
				Ogre::String paramId;
				Ogre::String paramValue;

				currentParam = applicationSettings->FirstChildElement();
				while(currentParam != 0)
				{

					paramId = currentParam->Value();

					if(paramId == "AllowDevConsole")
					{
						paramValue = currentParam->GetText();

						bool value = Ogre::StringConverter::parseBool(paramValue);
						this->applicationSettings.bAllowDevConsole = value;
					}


					if(paramId == "SandBoxMode")
					{
						paramValue = currentParam->GetText();

						bool value = Ogre::StringConverter::parseBool(paramValue);
						this->applicationSettings.bSandBoxMode = value;
					}


					if(paramId == "UseHardwarePhysX")
					{
						paramValue = currentParam->GetText();

						bool value = Ogre::StringConverter::parseBool(paramValue);
						this->applicationSettings.bUseHardwarePhysX = value;
					}


					if(paramId == "UseShadows")
					{
						paramValue = currentParam->GetText();

						bool value = Ogre::StringConverter::parseBool(paramValue);
						this->applicationSettings.bUseShadows = value;
					}


					if(paramId == "LogBenchmark")
					{
						paramValue = currentParam->GetText();

						bool value = Ogre::StringConverter::parseBool(paramValue);
						this->applicationSettings.bLogBenchmark = value;
					}



					if(paramId == "ServerAddress")
					{
						paramValue = currentParam->GetText();

						Ogre::String value = paramValue;
						this->applicationSettings.sServerAddress = value;
					}



					if(paramId == "Port")
					{
						paramValue = currentParam->GetText();

						int value = Ogre::StringConverter::parseInt(paramValue);
						this->applicationSettings.nPort = value;
					}



					currentParam = currentParam->NextSiblingElement();
				}
			}

		}

		settingsFile.Clear();
		return true;
	}
	else
	{
		return false;
	}
}

//-------------------------------------------------------------------------------------------------------------------

void AppSettings::saveSettings(void)
{
	Ogre::String value = "";

	root = new TiXmlElement( "SceneView_AppSettings" );  
		
		TiXmlElement * WaterSettings = new TiXmlElement("WaterSettings"); 

					TiXmlElement *MaxParticlesNode = new TiXmlElement("MaxParticles"); 
					value = Ogre::StringConverter::toString(waterSettings.mMaxParticles);
					MaxParticlesNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( MaxParticlesNode );  

					TiXmlElement *KernelRadiusMultiplierNode = new TiXmlElement("KernelRadiusMultiplier"); 
					value = Ogre::StringConverter::toString(waterSettings.mKernelRadiusMultiplier);
					KernelRadiusMultiplierNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( KernelRadiusMultiplierNode );  

					TiXmlElement *RestParticlesPerMetreNode = new TiXmlElement("RestParticlesPerMetre"); 
					value = Ogre::StringConverter::toString(waterSettings.mRestParticlesPerMetre);
					RestParticlesPerMetreNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( RestParticlesPerMetreNode ); 

					TiXmlElement *MotionLimitMultiplierNode = new TiXmlElement("MotionLimitMultiplier"); 
					value = Ogre::StringConverter::toString(waterSettings.mMotionLimitMultiplier);
					MotionLimitMultiplierNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( MotionLimitMultiplierNode );  

					TiXmlElement *PacketSizeMultiplierNode = new TiXmlElement("PacketSizeMultiplier"); 
					value = Ogre::StringConverter::toString(waterSettings.mPacketSizeMultiplier);
					PacketSizeMultiplierNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( PacketSizeMultiplierNode );  

					TiXmlElement *CollisionDistanceMultiplierNode = new TiXmlElement("CollisionDistanceMultiplier"); 
					value = Ogre::StringConverter::toString(waterSettings.mCollisionDistanceMultiplier);
					CollisionDistanceMultiplierNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( CollisionDistanceMultiplierNode );  

					TiXmlElement *StiffnessNode = new TiXmlElement("Stiffness"); 
					value = Ogre::StringConverter::toString(waterSettings.mStiffness);
					StiffnessNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( StiffnessNode ); 

					TiXmlElement *ViscosityNode = new TiXmlElement("Viscosity"); 
					value = Ogre::StringConverter::toString(waterSettings.mViscosity);
					ViscosityNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( ViscosityNode );  

					TiXmlElement *RestDensityNode = new TiXmlElement("RestDensity"); 
					value = Ogre::StringConverter::toString(waterSettings.mRestDensity);
					RestDensityNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( RestDensityNode );  

					TiXmlElement *StartHeightNode = new TiXmlElement("StartHeight"); 
					value = Ogre::StringConverter::toString(waterSettings.mStartHeight);
					StartHeightNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( StartHeightNode );  

					TiXmlElement *ParticleLifetimeNode = new TiXmlElement("ParticleLifetime"); 
					value = Ogre::StringConverter::toString(waterSettings.mParticleLifetime);
					ParticleLifetimeNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( ParticleLifetimeNode );  

					TiXmlElement *RateNode = new TiXmlElement("Rate"); 
					value = Ogre::StringConverter::toString(waterSettings.mRate);
					RateNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( RateNode );  

					TiXmlElement *FluidSpeedNode = new TiXmlElement("FluidSpeed"); 
					value = Ogre::StringConverter::toString(waterSettings.mFluidSpeed);
					FluidSpeedNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( FluidSpeedNode );  

					TiXmlElement *ReplusionCoefficientNode = new TiXmlElement("ReplusionCoefficient"); 
					value = Ogre::StringConverter::toString(waterSettings.mReplusionCoefficient);
					ReplusionCoefficientNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( ReplusionCoefficientNode );  

					TiXmlElement *DimensionXNode = new TiXmlElement("DimensionX"); 
					value = Ogre::StringConverter::toString(waterSettings.mDimensionX);
					DimensionXNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( DimensionXNode );  

					TiXmlElement *DimensionYNode = new TiXmlElement("DimensionY"); 
					value = Ogre::StringConverter::toString(waterSettings.mDimensionY);
					DimensionYNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( DimensionYNode );  

					TiXmlElement *ParticleSizeNode = new TiXmlElement("ParticleSize"); 
					value = Ogre::StringConverter::toString(waterSettings.mParticleSize);
					ParticleSizeNode->LinkEndChild( new TiXmlText( value.data() ) );
					WaterSettings->LinkEndChild( ParticleSizeNode );  

		root->LinkEndChild(WaterSettings);


		TiXmlElement * ApplicationSettings = new TiXmlElement("ApplicationSettings"); 

					TiXmlElement *AllowDevConsoleNode = new TiXmlElement("AllowDevConsole"); 
					value = Ogre::StringConverter::toString(applicationSettings.bAllowDevConsole);
					AllowDevConsoleNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( AllowDevConsoleNode );  

					TiXmlElement *SandBoxModeNode = new TiXmlElement("SandBoxMode"); 
					value = Ogre::StringConverter::toString(applicationSettings.bSandBoxMode);
					SandBoxModeNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( SandBoxModeNode );  


					TiXmlElement *UseHardwarePhysXNode = new TiXmlElement("UseHardwarePhysX"); 
					value = Ogre::StringConverter::toString(applicationSettings.bUseHardwarePhysX);
					UseHardwarePhysXNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( UseHardwarePhysXNode );  


					TiXmlElement *UseShadowsNode = new TiXmlElement("UseShadows"); 
					value = Ogre::StringConverter::toString(applicationSettings.bUseShadows);
					UseShadowsNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( UseShadowsNode );  


					TiXmlElement *LogBenchmarkNode = new TiXmlElement("LogBenchmark"); 
					value = Ogre::StringConverter::toString(applicationSettings.bLogBenchmark);
					LogBenchmarkNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( LogBenchmarkNode );  


					TiXmlElement *ServerAddressNode = new TiXmlElement("ServerAddress"); 
					value = applicationSettings.sServerAddress;
					ServerAddressNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( ServerAddressNode );  


					TiXmlElement *PortNode = new TiXmlElement("Port"); 
					value = Ogre::StringConverter::toString(applicationSettings.nPort);
					PortNode->LinkEndChild( new TiXmlText( value.data() ) );
					ApplicationSettings->LinkEndChild( PortNode );  

		root->LinkEndChild(ApplicationSettings);

	settingsFile.LinkEndChild( root ); 

	remove( "AppSettings.xml" );
	settingsFile.SaveFile( "AppSettings.xml" );
}

//-------------------------------------------------------------------------------------------------------------------

AppSettings::WaterSettings::WaterSettings(void)
{
	resetToDefault();
}

//-------------------------------------------------------------------------------------------------------------------

AppSettings::WaterSettings::~WaterSettings(void)
{
}

//-------------------------------------------------------------------------------------------------------------------

void AppSettings::WaterSettings::resetToDefault(void)
{
	//setting default fluid params
	mMaxParticles = 2500; //2500
    mKernelRadiusMultiplier = 2.0f;
    mRestParticlesPerMetre = 15.0f;
    mMotionLimitMultiplier = 3.0f;
    mPacketSizeMultiplier = 8;
    mCollisionDistanceMultiplier = 0.1f;
    mStiffness = 1.0f;
    mViscosity = 1.0f;
    mRestDensity = 1000.0f;
  
	//setting default emitter params
	mStartHeight = 1;
	mParticleLifetime = 50.0;
	mRate = 50; //50
	mFluidSpeed = 0.1;
	mReplusionCoefficient = 0.8f;
	mDimensionX = 0.1f;
	mDimensionY = 0.1f;
	mParticleSize = 4.0f;
}

//-------------------------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------------------------

AppSettings::ApplicationSettings::ApplicationSettings(void)
{
	resetToDefault();
}

//-------------------------------------------------------------------------------------------------------------------

AppSettings::ApplicationSettings::~ApplicationSettings(void)
{
}

//-------------------------------------------------------------------------------------------------------------------

void AppSettings::ApplicationSettings::resetToDefault(void)
{
	bAllowDevConsole = false;
	bSandBoxMode = true;
	bUseHardwarePhysX = true;
	bUseShadows = true;
	bLogBenchmark = false;
	sServerAddress = "localhost";
	nPort = 2000;
}

//-------------------------------------------------------------------------------------------------------------------